package com.banhujiu.spider.region.enums

import com.banhujiu.spider.region.conf.charsetName
import com.banhujiu.spider.region.conf.codeSize
import com.banhujiu.spider.region.enties.RegionEntry
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
import java.net.URL

/**
 * @author banhujiu
 * @date 2017/11/19 0019 21:29
 */
enum class AreaLevelEnum(var level: Short, var msg: String) {

    CHOSE(-1, "CHOSE") {
        override fun nextLevel(): AreaLevelEnum? = null
        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry = RegionEntry()
        override fun getLinks(url: String): ArrayList<Element> = ArrayList()
    },
    PROVINCE(1, "省/直辖市") {
        override fun nextLevel(): AreaLevelEnum = CITY
        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry {
            val region = RegionEntry()
            region.level = this.level
            region.pCode = null
            val href: String = link.attr("href")
            val arr: List<String> = href.split(".")
            var code: String = arr[0]
            if (code.length < codeSize) {
                for (i in 0 until codeSize - code.length) {
                    code += "0"
                }
            }
            region.code = code
            region.name = link.text()
            region.nextUrl = link.attr("abs:href")
            return region
        }

        override fun getLinks(url: String): ArrayList<Element> {
            val doc = Jsoup.parse(URL(url).openStream(), charsetName, url)
            return doc.select("tr.provincetr").select("a")
        }
    },
    CITY(2, "市") {
        override fun nextLevel(): AreaLevelEnum = AREA

        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry {
            val city = RegionEntry()
            city.level = this.level
            city.pCode = pRegionEntry.code
            val alist: Elements = link.select("a")
            val codeE: Element = alist[0]
            val codeN: Element = alist[1]
            var name: String? = codeN.text()
            if ("市辖区" == name) {
                name = pRegionEntry.name
            }
            city.code = codeE.text()
            city.name = name
            city.nextUrl = codeE.attr("abs:href")
            return city
        }

        override fun getLinks(url: String): ArrayList<Element> {
            val doc: Document = Jsoup.parse(URL(url).openStream(), charsetName, url)
            return doc.select("tr.citytr")
        }
    },
    AREA(3, "区/县") {
        override fun nextLevel(): AreaLevelEnum = STREET

        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry {
            val area = RegionEntry()
            area.pCode = pRegionEntry.code
            area.level = this.level
            var alist: Elements = link.select("a")
            if (alist.size > 0) {
                val codeE: Element = alist[0]
                area.code = codeE.text()
                area.nextUrl = codeE.attr("abs:href")
                val codeN = alist[1]
                val name = codeN.text()
                area.name = name
            } else {
                alist = link.select("td")
                area.code = alist[0].text()
                area.name = alist[1].text()
            }
            return area
        }

        override fun getLinks(url: String): ArrayList<Element> {
            val doc: Document = Jsoup.parse(URL(url).openStream(), charsetName, url)
            return doc.select("tr.countytr")
        }
    },
    STREET(4, "街巷道") {
        override fun nextLevel(): AreaLevelEnum = NEIGHBORHOOD

        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry {
            val street = RegionEntry()
            street.pCode = pRegionEntry.code
            street.level = this.level
            var alist: Elements = link.select("a")
            if (alist.size > 0) {
                val codeE: Element = alist[0]
                street.code = codeE.text()
                street.nextUrl = codeE.attr("abs:href")
                val codeN = alist[1]
                val name = codeN.text()
                street.name = name
            } else {
                alist = link.select("td")
                street.code = alist[0].text()
                street.name = alist[1].text()
            }
            return street
        }

        override fun getLinks(url: String): ArrayList<Element> {
            val doc = Jsoup.parse(URL(url).openStream(), charsetName, url)
            return doc.select("tr.towntr")
        }
    },
    NEIGHBORHOOD(5, "居委会等") {
        override fun nextLevel(): AreaLevelEnum? = null

        override fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry {
            val neighborhood = RegionEntry()
            neighborhood.pCode = pRegionEntry.code
            neighborhood.level = this.level
            val alist: Elements = link.select("td")

            val codeE: Element = alist[0]
            neighborhood.code = codeE.text()

            val codeN: Element = alist[2]
            neighborhood.name = codeN.text()

            return neighborhood
        }

        override fun getLinks(url: String): ArrayList<Element> {
            val doc = Jsoup.parse(URL(url).openStream(), charsetName, url)
            return doc.select("tr.villagetr")
        }
    };

    abstract fun getLinks(url: String): ArrayList<Element>
    abstract fun buildRegion(link: Element, pRegionEntry: RegionEntry): RegionEntry
    abstract fun nextLevel(): AreaLevelEnum?

    override fun toString(): String = "(name=$name,level=$level, msg='$msg')"


}
